#pragma once

#include <atomic>
#include <unordered_map>
#include <string>
#include <mutex>
#include <cassert>

#include "ShmService.hpp"
#include "ShmServiceNode.hpp"



/*
    ShmServiceManger 不保证多线程安全，自行加锁
*/

class ShmServiceManger
{
public:
    // 获取单例实例的函数
    static ShmServiceManger* GetInstance(std::string path = ShmService::SHM_PATH) {
        if (_instance == nullptr) {
            std::lock_guard<std::mutex> lock(_mutex);
            if (_instance == nullptr) {
                _instance = new ShmServiceManger(path);
                LOG_CYC(NORMAL, "创建 ShmServiceManger 实例，路径: %s", path.c_str());
            }
        }
        return _instance;
    }

    // 销毁单例实例的函数
    static void DestroyInstance() {
        std::lock_guard<std::mutex> lock(_mutex);
        if (_instance != nullptr) {
            delete _instance;
            _instance = nullptr;
            LOG_CYC(NORMAL, "销毁共享内存服务管理器实例", nullptr);
        }
    }

public:

    // 申请/连接共享内存
    ShmServiceNode* GetShmMemory(uint32_t size, int32_t shmId = -1) {
        ShmServiceNode* node = nullptr;
        if (shmId < 0) {
            int count = -1;
            while (count < 0) {
                if (_fileIds[_count % (MAX_SHM_COUNT - 1)] != nullptr) {
                    _count++; // 计数器加1
                }
                else {
                    count = _count % (MAX_SHM_COUNT - 1);
                }
            }

            std::string shmFileName = GenerateShmFileName(count); // 生成共享内存文件名

            // 创建并初始化共享内存服务实例
            node = new ShmServiceNode(size, shmFileName, count, true);

            if (node->_shmSvr == nullptr) {
                LOG_CYC(ERROR, "创建共享内存失败，文件名: %s", shmFileName.c_str());
                assert(node->_shmSvr != nullptr);
            }

            _fileIds[count] = node;
            _count++; // 计数器加1
            LOG_CYC(NORMAL, "成功创建共享内存，文件名: %s", shmFileName.c_str());
        }
        else {
            std::string shmFileName = GenerateShmFileName(shmId); // 生成共享内存文件名

            // 连接已经创建的共享内存服务实例
            node = new ShmServiceNode(size, shmFileName, shmId, false);

            if (node->_shmSvr == nullptr) {
                LOG_CYC(ERROR, "连接共享内存失败，文件名: %s", shmFileName.c_str());
                assert(node->_shmSvr != nullptr);
            }

            _fileIds[shmId] = node;// 将实例存储在映射中
        }

        return node ? node : nullptr; // 返回共享内存头部指针，如果失败则返回nullptr
    }

    // 释放共享内存文件
    void ReleaseShmMemory(int32_t fileId) {
        if (_fileIds[fileId] == nullptr) {
            LOG_CYC(FATAL, "共享内存文件不存在，shmFileId: %d", fileId);
            exit(1);
        }

        delete _fileIds[fileId]; // 释放 Node 实例
        _fileIds[fileId] = nullptr; // 先删除 _fileIds 中的元素
    }

    // 通过共享内存文件ID获取共享内存文件管理器
    ShmServiceNode* GetShmNodeByFileId(int fileId) {
        return _fileIds[fileId];
    }

    // 通过内存块信息得到当前进程的内存块地址
    void* GetShmPtr(const ShmMemoryBlock& block) {
        ShmServiceNode* shmNode = GetShmNodeByFileId(block._shmID);
        if (shmNode == nullptr) {
            LOG_CYC(WARNING, "查找内存块失败，共享内存文件ID错误，FileID：%d", block._shmID);
            return nullptr;
        }
        Span* span = shmNode->_pageMap[block._shmPos >> PAGE_SHIFT];
        if (span == nullptr || span->_isUse == false) {
            LOG_CYC(WARNING, "查找内存块失败，内存块未分配，FileID：%d，pos：%d", block._shmID, block._shmPos);
            return nullptr;
        }

        void* headPtr = shmNode->_shmSvr->GetShmHeader();
        return reinterpret_cast<void*>(reinterpret_cast<char*>(headPtr) + block._shmPos);
    }

private:

    // 生成共享内存文件名的函数
    std::string GenerateShmFileName(int64_t count) const {
        return std::string(_path) + "_" + std::to_string(count);
    }

private:
    // 私有构造函数
    ShmServiceManger(std::string& path)
        : _path(path)
        , _count(0) {
        memset(_fileIds, 0, sizeof(_fileIds));
    }

    ~ShmServiceManger() {}

    // 禁止拷贝构造和赋值
    ShmServiceManger(const ShmServiceManger&) = delete;
    ShmServiceManger& operator=(const ShmServiceManger&) = delete;

private:
    static ShmServiceManger* _instance; // 单例实例
    static std::mutex _mutex; // 单例互斥锁

    std::string _path;  // 路径
    uint32_t _count;    // 计数器
    ShmServiceNode* _fileIds[MAX_SHM_COUNT];
};

// 静态成员变量的定义和初始化
ShmServiceManger* ShmServiceManger::_instance = nullptr;
std::mutex ShmServiceManger::_mutex;
